package com.kaibes.core.base.util;

import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AesUtils {

    private static String algorithm = "AES";
    // AES 128位, 密钥16个字节，因为一个字节就是8位，所以 128 / 8 = 16

    public static class CBC {
        private static String AlgorithmProvider = "AES/CBC/PKCS5Padding"; // 算法/模式/补码方式

        public static byte[] encrypt(byte[] bytes, String key, String iv)
                throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
                BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
            SecretKey secretKey = new SecretKeySpec(StringUtils.getBytes(key), algorithm);
            Cipher cipher = Cipher.getInstance(AlgorithmProvider);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(StringUtils.getBytes(iv));
            cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivParameterSpec);
            return cipher.doFinal(bytes);
        }

        public static byte[] decrypt(byte[] bytes, String key, String iv)
                throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
                InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
            SecretKey secretKey = new SecretKeySpec(StringUtils.getBytes(key), algorithm);
            Cipher cipher = Cipher.getInstance(AlgorithmProvider);
            IvParameterSpec ivParameterSpec = new IvParameterSpec(StringUtils.getBytes(iv));
            cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
            return cipher.doFinal(bytes);
        }
        
        public static String decrypt2String64(String str, String key, String iv) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException {
            return StringUtils.getString(decrypt(Base64.getDecoder().decode(str), key, iv));
        }

        public static String encrypt2String64(String str, String key, String iv) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
                BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
            return Base64.getEncoder().encodeToString(encrypt(StringUtils.getBytes(str), key, iv));
        }
    }
    
    public static class ECB {
        private static String AlgorithmProvider = "AES/ECB/PKCS5Padding"; // 算法/模式/补码方式

        public static byte[] encrypt(byte[] bytes, String key)
                throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
                BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
            SecretKey secretKey = new SecretKeySpec(StringUtils.getBytes(key), algorithm);
            Cipher cipher = Cipher.getInstance(AlgorithmProvider);
            cipher.init(Cipher.ENCRYPT_MODE, secretKey);
            byte[] cipherBytes = cipher.doFinal(bytes);
            return cipherBytes;
        }

        public static byte[] decrypt(byte[] bytes, String key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException  {
            SecretKey secretKey = new SecretKeySpec(StringUtils.getBytes(key), algorithm);
            Cipher cipher = Cipher.getInstance(AlgorithmProvider);
            cipher.init(Cipher.DECRYPT_MODE, secretKey);
            return cipher.doFinal(bytes);
        }

        public static String encrypt2String64(String str, String key)
                throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException,
                BadPaddingException, UnsupportedEncodingException, InvalidAlgorithmParameterException {
            return Base64.getEncoder().encodeToString(encrypt(StringUtils.getBytes(str), key));
        }
        public static String decrypt2String64(String str, String key) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException  {
            return StringUtils.getString(decrypt(Base64.getDecoder().decode(str), key));
        }

    }

}
